import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import n4j.call_liantong as nclt
import math


def guiyihua(zuobiao, nodenum, length):
    like_juli = int(nodenum ** 0.5) * length
    temp = zuobiao.copy()
    jianfa = temp[0].copy()
    for i in temp:
        i[0] = i[0] - jianfa[0]
        i[1] = i[1] - jianfa[1]
    # print(temp)
    if len(temp) > 1:
        juli = 0
        for i in temp:
            juli = juli + abs(i[0]) + abs(i[1])
        juli = juli / (2 * len(zuobiao) - 2)
        beilv = like_juli / juli
        for i in temp:
            i[0] = int(i[0] * beilv)
            i[1] = int(i[1] * beilv)
        # print(juli, like_juli)
        # print(temp)
    return temp


def tongxinyuan(geshu, qidian, zhongdian):
    1


class Map:
    def __init__(self, message=[], bdzmess=[], initial=0):
        self.message = message
        self.bdzmess = bdzmess

        nodeid = []
        nodelable = []
        for i in self.message:
            if (i['a'].identity in nodeid) == 0:
                nodeid.append(i['a'].identity)
                nodelable.append(i['a'].labels)
            if (i['b'].identity in nodeid) == 0:
                nodeid.append(i['b'].identity)
                nodelable.append(i['b'].labels)
        map = np.zeros((len(nodeid), len(nodeid)))
        edgelabel = [[0 for i in range(len(nodeid))] for i in range(len(nodeid))]
        for i in self.message:
            x = nodeid.index(i['a'].identity)
            y = nodeid.index(i['b'].identity)
            map[x, y] = 1
            map[y, x] = 1
            edgelabel[x][y] = i['r']['dkx_id']
            edgelabel[y][x] = i['r']['dkx_id']

        self.nodeid = nodeid
        self.nodelabel = nodelable
        self.map = map
        self.edge_dkxid = edgelabel
        self.edgenum = len(self.message)
        self.nodenum = len(nodeid)
        zuo = guiyihua(self.bdzmess[['zuobiaox', 'zuobiaoy']].values, self.nodenum, initial)
        self.bdz_gyhuazuobiao = np.array(zuo)
        self.bdzmess[['zuobiaox', 'zuobiaoy']] = zuo
        self.Firstzuobiao = np.zeros((self.nodenum, 2))
        self.nodeweight = np.zeros((self.nodenum, 1))
        self.dkxline = []
        self.Dkxline = {}
        self.bdz = []
        self.mianline = []
        self.subbreak = []

        #  加虚拟点拉着变电站
        virmap = map.copy()
        virmap = np.vstack((virmap, np.zeros((len(self.bdzmess['zuobiaox']), self.nodenum))))
        virmap = np.hstack((virmap, np.zeros((self.nodenum+len(self.bdzmess['zuobiaox']), len(self.bdzmess['zuobiaox'])))))
        self.virmap = virmap
        self.virzuobiao = []
        self.virnodeweight = []

    def firstzuo(self):
        bdz = []
        conbreak = []
        self.virzuobiao = []
        self.virnodeweight = []
        for i in self.bdzmess['id']:
            bdz.append(self.nodeid.index(i))
        for i in self.nodelabel:
            if i == ['ContactBreaker']:
                conbreak.append(self.nodelabel.index(i))
        print('eeeee', conbreak)
        self.Firstzuobiao[bdz] = self.bdzmess[['zuobiaox', 'zuobiaoy']].values
        self.bdz = bdz
        move_node = [i for i in range(self.nodenum)]
        move_node = list(set(move_node) ^ set(bdz))
        self.nodeweight[bdz] = 10  # 1.13 为30
        self.nodeweight[move_node] = 10
        self.nodeweight[conbreak] = 10
        randx = np.random.randint(-2000, 2000, len(move_node))
        randy = np.random.randint(-2000, 2000, len(move_node))
        randx = np.zeros((len(move_node), 1))
        randy = np.zeros((len(move_node), 1))
        randzuobiao = np.array([randx, randy]).T
        self.Firstzuobiao[move_node] = randzuobiao
        bian_no = self.map[move_node, :]
        # print(bian_no.shape)
        # print(self.nodeweight)
        return move_node, bdz

    def subtosub(self):
        def dfs(mmap, n, queue, que, dkx_id, newsub):
            global Dkxline, dkxline
            queue.append(mmap.nodeid[n])
            que.append(n)
            visited[n] = 1

            if str(mmap.nodelabel[n]) == ':ContactBreaker':
                temp = queue.copy()
                temp = [mmap.nodeid[newsub]] + temp
                tempp = que.copy()
                tempp = [newsub] + tempp
                Dkxline[str(tempp)] = dkx_id

                dkxline.append(tempp)
            else:
                for j in range(mmap.nodenum):
                    if mmap.edge_dkxid[n][j] == dkx_id and visited[j] == 0:
                        dfs(mmap, j, queue, que, dkx_id, newsub)
            queue.pop()
            que.pop()

        subs = self.firstzuo()[1]
        global Dkxline, dkxline
        dkxline = []
        Dkxline = {}
        for i in subs:
            for j in range(self.nodenum):
                if self.edge_dkxid[i][j] != 0:
                    # Dkxline[self.edgelabel[i][j]] = []
                    visited = [0 for i in range(self.nodenum)]
                    dfs(self, j, [], [], self.edge_dkxid[i][j], i)
        self.dkxline = dkxline
        self.Dkxline = Dkxline
        return Dkxline, dkxline

    def bdz_change(self):
        pass

    def stosline(self):
        def laxian(line):
            qidian = self.Firstzuobiao[line[0]]
            zhongdian = self.Firstzuobiao[line[-1]]
            dx = (zhongdian[0] - qidian[0]) / (len(line) - 1)
            dy = (zhongdian[1] - qidian[1]) / (len(line) - 1)
            nnum = np.array([[dx, dy] for i in range(len(line))])
            n = [[i] for i in range(len(line))]
            dzuobiao = nnum * n
            qizuobiao = [qidian for i in range(len(line))]
            dzuobiao = dzuobiao + qizuobiao
            return dzuobiao

        mianline = []
        subbreak = []
        mianlines = []
        miandkxlines = []
        for dline in self.dkxline:
            tempdkxline = self.dkxline.copy()
            del tempdkxline[self.dkxline.index(dline)]
            for i in self.dkxline:
                if i[-1] == dline[-1]:
                    if i[0] != dline[0]:
                        is_nan = 1
                        for line in range(len(miandkxlines)):
                            if miandkxlines[line][0][0] == i[0]:
                                miandkxlines[line].append(i)
                                is_nan = 0
                        if is_nan == 1:
                            miandkxlines.append([i])
                        templine = dline.copy()
                        conbreak = templine.pop()
                        templine.reverse()
                        templine = i + templine
                        if (set(templine) < set(mianline)) is False:
                            # print('xxxx', templine)
                            sub_break_sub = [templine[0], conbreak, templine[-1]]
                            # self.Firstzuobiao[sub_break_sub] = laxian(sub_break_sub)
                            self.Firstzuobiao[templine] = laxian(templine)
                            # print(self.Firstzuobiao[templine])
                            mianlines.append(templine)
                            subbreak = list(set(subbreak) | set(sub_break_sub))
                            mianline = list(set(templine) | set(mianline))
        self.mianline = mianline
        print('对线', mianlines)
        self.subbreak = subbreak
        # for i in miandkxlines:
        #     1
        # def mianlineflower(nodeline):
        #     otherside = []
        #     for i in nodeline:
        #         for j in mianlines:
        #             if i[-1] in j:
        #                 if j[0] == i[0]:
        #                     otherside.append(j[-1])
        #                 else:
        #                     otherside.append(j[0])
        #     num = 1
        #     for i in range(len(otherside)):
        #         tempother = otherside.copy()
        #         del tempother[i]
        #         for j in tempother:
        #             if j == otherside[i]:
        #                 num = num + 1
        #
        # print(mianlines)
        return miandkxlines

    def virnode(self):
        # 加上拉着的坐标，我也不知道写啥备注，加油吧，以后的我
        for i in range(len(self.bdz)):
            self.virmap[self.nodenum + i][self.bdz[i]] = 1
            self.virmap[self.bdz[i]][self.nodenum + i] = 1
        self.virzuobiao = np.vstack((self.Firstzuobiao, self.bdz_gyhuazuobiao))
        self.virnodeweight = np.vstack((self.nodeweight, np.zeros((len(self.bdz), 1))))


if __name__ == '__main__':
    a = nclt.main(1)
    weiz = nclt.main(0)
    weiz1 = weiz.copy()
    print('我我问问', weiz)
    g = Map(a, weiz)
    # print(g.map.shape, g.edgenum)
    print('我我问问1', weiz1)
    print(type(weiz['zuobiaox']))
    print(weiz[['zuobiaox', 'zuobiaoy']].values)
    zuo = guiyihua(weiz1[['zuobiaox', 'zuobiaoy']].values, g.nodenum, 30)
    print(zuo[:, 0])
    weiz[['zuobiaox', 'zuobiaoy']] = zuo

    print(weiz)
    a = g.firstzuo()
    print(g.nodeid)
    print(g.nodelabel)

    plt.scatter(zuo[:, 0], zuo[:, 1])
    plt.show()

    b, d = g.subtosub()
    print(d)
    print(b)
    print(g.stosline())
    g.virnode()
    print(g.map)
    print(g.virmap)
    print(g.virmap.shape)
    print(g.bdz_gyhuazuobiao)
    print(g.bdz)
    print(g.mianline)
    print(g.dkxline)